﻿namespace Pathfinder.Base.UI
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using Bridge.UI;
    using Pathfinder.Base.Constructs;

    /// <summary>
    /// Interaction logic for RecalculateHP.xaml
    /// </summary>
    public partial class RecalculateHP : UserControl
    {
        public static void ShowRecalculateHPWindow(PathfinderCharacter pathfinderCharacter)
        {
            RecalculateHP recalculateHP = new RecalculateHP(pathfinderCharacter);
            CustomPopup customPopup = new CustomPopup(recalculateHP);
            recalculateHP.mCustomPopup = customPopup;
            customPopup.ShowDialog();
        }

        public RecalculateHP(PathfinderCharacter pathfinderCharacter)
        {
            InitializeComponent();

            mCharacter = pathfinderCharacter;
            int dice = 1;
            foreach (KeyValuePair<int, int> hd in mCharacter.HitDice)
            {
                for (int i = 0; i < hd.Value; i++)
                {
                    mHitDice.Add(new HitDice()
                    {
                        DiceNumber = dice++,
                        DiceSize = hd.Key,
                        DiceFace = hd.Value
                    });
                }
            }
            SetAverage(false);
            foreach (HitDice hitDice in mHitDice)
            {
                hitDice.PropertyChanged += new PropertyChangedEventHandler(hitDice_PropertyChanged);
            }

            listBoxHitDice.ItemsSource = mHitDice;
            int conBonus = (int)Math.Floor((double)(mCharacter.TotalStats[StatType.Constitution] - 10) / 2);
            int conBonusHP = conBonus * mCharacter.TotalHitDice;
            textBlockConBonus.Text = (conBonus >= 0 ? "+" : string.Empty) + conBonus.ToString();
            textBlockConBonusHP.Text = conBonusHP.ToString();
            textBoxBonusHP.Text = mCharacter.BonusHP.ToString();

            CalculateHP();
        }

        private PathfinderCharacter mCharacter;
        private ObservableCollection<HitDice> mHitDice = new ObservableCollection<HitDice>();
        private CustomPopup mCustomPopup;

        private void SetAverage(bool plusOne)
        {
            foreach (HitDice hitDice in mHitDice)
            {
                hitDice.DiceFace = (hitDice.DiceSize / 2) + 1 + (plusOne ? 1 : 0);
            }
        }

        private void SetMaximum()
        {
            foreach (HitDice hitDice in mHitDice)
            {
                hitDice.DiceFace = hitDice.DiceSize;
            }
        }

        private int CalculateHP()
        {
            if (mCharacter == null) return -1;

            int totalHP = 0;
            foreach (HitDice hitDice in mHitDice)
            {
                totalHP += hitDice.DiceFace;
            }
            int bonusHP = 0;
            if (!int.TryParse(textBoxBonusHP.Text, out bonusHP))
            {
                bonusHP = 0;
            }
            totalHP += bonusHP;
            int conBonus = mCharacter.TotalHitDice * (int)Math.Floor((double)(mCharacter.TotalStats[StatType.Constitution] - 10) / 2);
            totalHP += conBonus;
            textBlockTotalHP.Text = totalHP.ToString();

            return totalHP;
        }

        private void buttonAvgPlus1_Click(object sender, RoutedEventArgs e)
        {
            SetAverage(true);
        }

        private void buttonAvg_Click(object sender, RoutedEventArgs e)
        {
            SetAverage(false);
        }

        private void buttonMax_Click(object sender, RoutedEventArgs e)
        {
            SetMaximum();
        }

        private void textBoxBonusHP_TextChanged(object sender, TextChangedEventArgs e)
        {
            CalculateHP();
        }

        private void buttonOK_Click(object sender, RoutedEventArgs e)
        {
            int bonusHP = 0;
            if (!int.TryParse(textBoxBonusHP.Text, out bonusHP))
            {
                bonusHP = 0;
            }
            mCharacter.BonusHP = bonusHP;
            mCharacter.MaximumHitPoints = CalculateHP();

            Dictionary<int, int> dice = new Dictionary<int, int>() { { 6, 0 }, { 8, 0 }, { 10, 0 }, { 12, 0 } };
            foreach (HitDice hitDice in mHitDice)
            {
                dice[hitDice.DiceSize]++;
            }
            foreach (KeyValuePair<int, int> hd in dice)
            {
                mCharacter.SetHitDice(hd.Key, hd.Value);
            }

            if (mCustomPopup != null && mCustomPopup.IsVisible)
            {
                mCustomPopup.Close();
            }
        }

        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            if (mCustomPopup != null && mCustomPopup.IsVisible)
            {
                mCustomPopup.Close();
            }
        }

        private void hitDice_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals("DiceFace", StringComparison.OrdinalIgnoreCase))
            {
                CalculateHP();
            }
        }
    }
}
